import { alova } from '$utils/request';
import { writable } from 'svelte/store';
import { mergeOptions } from './pageInit';
import { forTitle } from '$utils/forTitle';
import { createMessage, type ShowMsgResultType } from '$components/basic/message';
import { goto } from '$utils/intercept';
import { onDestroy, onMount } from 'svelte';
import type { Method } from 'alova';

export type ReqParam = string | ((params?: IObject) => Promise<IObject>);
export type GetUrl = string | (() => string);

export type handleOptions = {
	callback?: (res: IObject) => void;
	type?: 'get' | 'post';
	isInit?: boolean;
	loadingInitial?: boolean;
	params?: IObject; // 请求参数
	handle?: (res: IObject) => void;
	msg?: ShowMsgResultType;
};

export async function handleReq<T>(req: ReqParam, options: handleOptions) {
	const defaultOpt: handleOptions = {
		type: 'post',
		isInit: true,
		loadingInitial: true
	};

	const loading = writable<boolean>(options.loadingInitial!);
	const result = writable<T | null>(null);
	let error: boolean = false;

	mergeOptions(options, defaultOpt);

	const reqInfo = () =>
		alova?.[forTitle(options.type!)](req, options.params).then((res) => {
			if (res.code === 401) {
				// TODO: 跳转到登录页面
				// clearLoginState();

				console.log(options.msg);

				if (options.msg) options.msg.instance.update_loading_to_error('user not login');
				else createMessage({ type: 'warning', message: 'user not login' });
				error = true;
				goto('/login');
				return;
			}

			if (res.code === 1) {
				options.handle?.(res);
				result.set(res as T);
				return res as T;
			}

			if (options.msg) options.msg.instance.update_loading_to_error('request failed');
			else createMessage({ type: 'danger', message: 'request failed' });
			error = true;
		});

	if (options.isInit) {
		await reqInfo();
	}

	return { loading, result, error, reqInfo };
}

export function handleReqMounted<T>(req: GetUrl, options: handleOptions) {
	const defaultOpt: handleOptions = {
		type: 'post',
		isInit: true,
		loadingInitial: true
	};

	mergeOptions(options, defaultOpt);

	const loading = writable<boolean>(options.loadingInitial!);
	const result = writable<T | null>(null);
	let method: Method | null = null;
	let error: boolean = false;

	const openLoading = () => loading.set(true);
	const closeLoading = () => loading.set(false);

	const reqInfo = (useLoading: boolean = true) => {
		const url = typeof req === 'string' ? req : (req as () => string)();
		method = alova?.[forTitle(options.type!)](url, options.params);
		return (
			useLoading && openLoading(),
			method?.then((res) => {
				if (res.code === 401) {
					// TODO: 跳转到登录页面
					// clearLoginState();

					console.log(options.msg);

					if (options.msg) options.msg.instance.update_loading_to_error('user not login');
					else createMessage({ type: 'warning', message: 'user not login' });
					error = true;
					goto('/login');
					return;
				}

				if (res.code === 1 || res.code === undefined) {
					options.handle?.(res);
					result.set(res as T);
					if (useLoading) closeLoading();
					return res as T;
				}

				if (options.msg) options.msg.instance.update_loading_to_error('request failed');
				else createMessage({ type: 'danger', message: 'request failed' });
				error = true;
				if (useLoading) closeLoading();
			})
		);
	};

	if (options.isInit) {
		onMount(reqInfo as () => void);
	}

	onDestroy(() => method?.abort());

	return { method, loading, result, error, reqInfo, closeLoading };
}
